package util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

/**
 * 文件工具
 * 
 * FileUtil
 * 
 * GeBing 2012-11-16 下午8:04:05
 * 
 * @version 1.0.0
 * 
 */
public class FileUtil {
  // 复制jar
  public static void copyJar(File src, File des) throws FileNotFoundException, IOException {
    JarInputStream jarIn = new JarInputStream(new BufferedInputStream(new FileInputStream(src)));
    Manifest manifest = jarIn.getManifest();
    JarOutputStream jarOut = null;
    if (manifest == null) {
      jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(des)));
    } else {
      jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(des)), manifest);
    }

    byte[] bytes = new byte[1024];
    while (true) {
      // 重点
      ZipEntry entry = jarIn.getNextJarEntry();
      if (entry == null)
        break;
      jarOut.putNextEntry(entry);

      int len = jarIn.read(bytes, 0, bytes.length);
      while (len != -1) {
        jarOut.write(bytes, 0, len);
        len = jarIn.read(bytes, 0, bytes.length);
      }
      LoggerUtils.profileDebug("Copyed: " + entry.getName());
      // jarIn.closeEntry();
      // jarOut.closeEntry();
      String a = new String();
      a.length();
    }
    jarIn.close();
    jarOut.finish();
    jarOut.close();
  }

  // 解压jar
  public static void unJar(File src, File desDir) throws FileNotFoundException, IOException {
    JarInputStream jarIn = new JarInputStream(new BufferedInputStream(new FileInputStream(src)));
    if (!desDir.exists())
      desDir.mkdirs();
    byte[] bytes = new byte[1024];

    while (true) {
      ZipEntry entry = jarIn.getNextJarEntry();
      if (entry == null)
        break;

      File desTemp = new File(desDir.getAbsoluteFile() + File.separator + entry.getName());

      if (entry.isDirectory()) { // jar条目是空目录
        if (!desTemp.exists())
          desTemp.mkdirs();
        LoggerUtils.profileDebug("MakeDir: " + entry.getName());
      } else { // jar条目是文件
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(desTemp));
        int len = jarIn.read(bytes, 0, bytes.length);
        while (len != -1) {
          out.write(bytes, 0, len);
          len = jarIn.read(bytes, 0, bytes.length);
        }

        out.flush();
        out.close();

        LoggerUtils.profileDebug("Copyed: " + entry.getName());
      }
      jarIn.closeEntry();
    }

    // 解压Manifest文件
    Manifest manifest = jarIn.getManifest();
    if (manifest != null) {
      File manifestFile = new File(desDir.getAbsoluteFile() + File.separator + JarFile.MANIFEST_NAME);
      if (!manifestFile.getParentFile().exists())
        manifestFile.getParentFile().mkdirs();
      BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(manifestFile));
      manifest.write(out);
      out.close();
    }

    // 关闭JarInputStream
    jarIn.close();
  }

  // 复制jar by JarFile
  public static void copyJarByJarFile(File src, File des) throws IOException {
    // 重点
    JarFile jarFile = new JarFile(src);
    Enumeration<JarEntry> jarEntrys = jarFile.entries();
    JarOutputStream jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(des)));
    byte[] bytes = new byte[1024];

    while (jarEntrys.hasMoreElements()) {
      JarEntry entryTemp = jarEntrys.nextElement();
      jarOut.putNextEntry(entryTemp);
      BufferedInputStream in = new BufferedInputStream(jarFile.getInputStream(entryTemp));
      int len = in.read(bytes, 0, bytes.length);
      while (len != -1) {
        jarOut.write(bytes, 0, len);
        len = in.read(bytes, 0, bytes.length);
      }
      in.close();
      jarOut.closeEntry();
      LoggerUtils.profileDebug("Copyed: " + entryTemp.getName());
    }

    jarOut.finish();
    jarOut.close();
    jarFile.close();
  }

  // 解压jar文件by JarFile
  public static void unJarByJarFile(File src, File desDir) throws FileNotFoundException, IOException {
    JarFile jarFile = new JarFile(src);
    Enumeration<JarEntry> jarEntrys = jarFile.entries();
    if (!desDir.exists())
      desDir.mkdirs(); // 建立用户指定存放的目录
    byte[] bytes = new byte[1024];

    while (jarEntrys.hasMoreElements()) {
      ZipEntry entryTemp = jarEntrys.nextElement();
      File desTemp = new File(desDir.getAbsoluteFile() + File.separator + entryTemp.getName());

      if (entryTemp.isDirectory()) { // jar条目是空目录
        if (!desTemp.exists())
          desTemp.mkdirs();
        LoggerUtils.profileDebug("makeDir" + entryTemp.getName());
      } else { // jar条目是文件
        // 因为manifest的Entry是"META-INF/MANIFEST.MF",写出会报"FileNotFoundException"
        File desTempParent = desTemp.getParentFile();
        if (!desTempParent.exists())
          desTempParent.mkdirs();

        BufferedInputStream in = new BufferedInputStream(jarFile.getInputStream(entryTemp));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(desTemp));

        int len = in.read(bytes, 0, bytes.length);
        while (len != -1) {
          out.write(bytes, 0, len);
          len = in.read(bytes, 0, bytes.length);
        }

        in.close();
        out.flush();
        out.close();

        LoggerUtils.profileDebug("Copyed: " + entryTemp.getName());
      }
    }

    jarFile.close();
  }

  public static void delete(String url) {
    if (StringUtils.isNotBlank(url)) {
      delete(new File(url));
    }
  }

  public static void delete(File file) {
    if (file != null && file.exists()) {
      if (file.isDirectory()) {
        for (String fileName : file.list()) {
          delete(new File(file.getPath() + File.separator + fileName));
        }
      }
      file.delete();
    }
  }
}